// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace System.Tests
{
    public abstract class RealFormatterTestsBase
    {
        // The following methods need to be implemented for the tests to run:
        protected abstract string InvariantToStringDouble(double d, string format);
        protected abstract string InvariantToStringSingle(float f, string format);

        [Theory]
        [InlineData(double.Epsilon, "\u00A40.00")]
        [InlineData(double.MaxValue, "\u00A4179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00")]
        [InlineData(Math.E, "\u00A42.72")]
        [InlineData(Math.PI, "\u00A43.14")]
        [InlineData(0.0, "\u00A40.00")]
        [InlineData(0.0046, "\u00A40.00")]
        [InlineData(0.005, "\u00A40.01")]
        [InlineData(0.125, "\u00A40.12")]
        [InlineData(0.5, "\u00A40.50")]
        [InlineData(0.51, "\u00A40.51")]
        [InlineData(0.56789, "\u00A40.57")]
        [InlineData(0.84551240822557006, "\u00A40.85")]
        [InlineData(1.0, "\u00A41.00")]
        [InlineData(505.0, "\u00A4505.00")]
        [InlineData(506.0, "\u00A4506.00")]
        [InlineData(545.0, "\u00A4545.00")]
        [InlineData(545.1, "\u00A4545.10")]
        [InlineData(555.0, "\u00A4555.00")]
        [InlineData(65747.125, "\u00A465,747.12")]
        [InlineData(1844674407370955.25, "\u00A41,844,674,407,370,955.25")]
        public void TestFormatterDouble_C(double value, string expectedResult) => TestFormatterDouble_Standard(value, "C", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "\u00A40")]
        [InlineData(double.MaxValue, "\u00A4179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368")]
        [InlineData(Math.E, "\u00A43")]
        [InlineData(Math.PI, "\u00A43")]
        [InlineData(0.0, "\u00A40")]
        [InlineData(0.0046, "\u00A40")]
        [InlineData(0.005, "\u00A40")]
        [InlineData(0.125, "\u00A40")]
        [InlineData(0.5, "\u00A40")]
        [InlineData(0.51, "\u00A41")]
        [InlineData(0.56789, "\u00A41")]
        [InlineData(0.84551240822557006, "\u00A41")]
        [InlineData(1.0, "\u00A41")]
        [InlineData(505.0, "\u00A4505")]
        [InlineData(506.0, "\u00A4506")]
        [InlineData(545.0, "\u00A4545")]
        [InlineData(545.1, "\u00A4545")]
        [InlineData(555.0, "\u00A4555")]
        [InlineData(65747.125, "\u00A465,747")]
        [InlineData(1844674407370955.25, "\u00A41,844,674,407,370,955")]
        public void TestFormatterDouble_C0(double value, string expectedResult) => TestFormatterDouble_Standard(value, "C0", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "\u00A40.00")]
        [InlineData(double.MaxValue, "\u00A4179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00")]
        [InlineData(Math.E, "\u00A42.72")]
        [InlineData(Math.PI, "\u00A43.14")]
        [InlineData(0.0, "\u00A40.00")]
        [InlineData(0.0046, "\u00A40.00")]
        [InlineData(0.005, "\u00A40.01")]
        [InlineData(0.125, "\u00A40.12")]
        [InlineData(0.5, "\u00A40.50")]
        [InlineData(0.51, "\u00A40.51")]
        [InlineData(0.56789, "\u00A40.57")]
        [InlineData(0.84551240822557006, "\u00A40.85")]
        [InlineData(1.0, "\u00A41.00")]
        [InlineData(505.0, "\u00A4505.00")]
        [InlineData(506.0, "\u00A4506.00")]
        [InlineData(545.0, "\u00A4545.00")]
        [InlineData(545.1, "\u00A4545.10")]
        [InlineData(555.0, "\u00A4555.00")]
        [InlineData(65747.125, "\u00A465,747.12")]
        [InlineData(1844674407370955.25, "\u00A41,844,674,407,370,955.25")]
        public void TestFormatterDouble_C2(double value, string expectedResult) => TestFormatterDouble_Standard(value, "C2", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "\u00A40.0000")]
        [InlineData(double.MaxValue, "\u00A4179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.0000")]
        [InlineData(Math.E, "\u00A42.7183")]
        [InlineData(Math.PI, "\u00A43.1416")]
        [InlineData(0.0, "\u00A40.0000")]
        [InlineData(0.0046, "\u00A40.0046")]
        [InlineData(0.005, "\u00A40.0050")]
        [InlineData(0.125, "\u00A40.1250")]
        [InlineData(0.5, "\u00A40.5000")]
        [InlineData(0.51, "\u00A40.5100")]
        [InlineData(0.56789, "\u00A40.5679")]
        [InlineData(0.84551240822557006, "\u00A40.8455")]
        [InlineData(1.0, "\u00A41.0000")]
        [InlineData(505.0, "\u00A4505.0000")]
        [InlineData(506.0, "\u00A4506.0000")]
        [InlineData(545.0, "\u00A4545.0000")]
        [InlineData(545.1, "\u00A4545.1000")]
        [InlineData(555.0, "\u00A4555.0000")]
        [InlineData(65747.125, "\u00A465,747.1250")]
        [InlineData(1844674407370955.25, "\u00A41,844,674,407,370,955.2500")]
        public void TestFormatterDouble_C4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "C4", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "\u00A40.00000000000000000000")]
        [InlineData(double.MaxValue, "\u00A4179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00000000000000000000")]
        [InlineData(Math.E, "\u00A42.71828182845904509080")]
        [InlineData(Math.PI, "\u00A43.14159265358979311600")]
        [InlineData(0.0, "\u00A40.00000000000000000000")]
        [InlineData(0.0046, "\u00A40.00459999999999999992")]
        [InlineData(0.005, "\u00A40.00500000000000000010")]
        [InlineData(0.125, "\u00A40.12500000000000000000")]
        [InlineData(0.5, "\u00A40.50000000000000000000")]
        [InlineData(0.51, "\u00A40.51000000000000000888")]
        [InlineData(0.56789, "\u00A40.56789000000000000590")]
        [InlineData(0.84551240822557006, "\u00A40.84551240822557005572")]
        [InlineData(1.0, "\u00A41.00000000000000000000")]
        [InlineData(505.0, "\u00A4505.00000000000000000000")]
        [InlineData(506.0, "\u00A4506.00000000000000000000")]
        [InlineData(545.0, "\u00A4545.00000000000000000000")]
        [InlineData(545.1, "\u00A4545.10000000000002273737")]
        [InlineData(555.0, "\u00A4555.00000000000000000000")]
        [InlineData(65747.125, "\u00A465,747.12500000000000000000")]
        [InlineData(1844674407370955.25, "\u00A41,844,674,407,370,955.25000000000000000000")]
        public void TestFormatterDouble_C20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "C20", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "4.940656E-324")]
        [InlineData(double.MaxValue, "1.797693E+308")]
        [InlineData(Math.E, "2.718282E+000")]
        [InlineData(Math.PI, "3.141593E+000")]
        [InlineData(0.0, "0.000000E+000")]
        [InlineData(0.0046, "4.600000E-003")]
        [InlineData(0.005, "5.000000E-003")]
        [InlineData(0.125, "1.250000E-001")]
        [InlineData(0.5, "5.000000E-001")]
        [InlineData(0.51, "5.100000E-001")]
        [InlineData(0.56789, "5.678900E-001")]
        [InlineData(0.84551240822557006, "8.455124E-001")]
        [InlineData(1.0, "1.000000E+000")]
        [InlineData(505.0, "5.050000E+002")]
        [InlineData(506.0, "5.060000E+002")]
        [InlineData(545.0, "5.450000E+002")]
        [InlineData(545.1, "5.451000E+002")]
        [InlineData(555.0, "5.550000E+002")]
        [InlineData(65747.125, "6.574712E+004")]
        [InlineData(1844674407370955.25, "1.844674E+015")]
        public void TestFormatterDouble_E(double value, string expectedResult) => TestFormatterDouble_Standard(value, "E", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "5E-324")]
        [InlineData(double.MaxValue, "2E+308")]
        [InlineData(Math.E, "3E+000")]
        [InlineData(Math.PI, "3E+000")]
        [InlineData(0.0, "0E+000")]
        [InlineData(0.0046, "5E-003")]
        [InlineData(0.005, "5E-003")]
        [InlineData(0.125, "1E-001")]
        [InlineData(0.5, "5E-001")]
        [InlineData(0.51, "5E-001")]
        [InlineData(0.56789, "6E-001")]
        [InlineData(0.84551240822557006, "8E-001")]
        [InlineData(1.0, "1E+000")]
        [InlineData(505.0, "5E+002")]
        [InlineData(506.0, "5E+002")]
        [InlineData(545.0, "5E+002")]
        [InlineData(545.1, "5E+002")]
        [InlineData(555.0, "6E+002")]
        [InlineData(65747.125, "7E+004")]
        [InlineData(1844674407370955.25, "2E+015")]
        public void TestFormatterDouble_E0(double value, string expectedResult) => TestFormatterDouble_Standard(value, "E0", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "4.94E-324")]
        [InlineData(double.MaxValue, "1.80E+308")]
        [InlineData(Math.E, "2.72E+000")]
        [InlineData(Math.PI, "3.14E+000")]
        [InlineData(0.0, "0.00E+000")]
        [InlineData(0.0046, "4.60E-003")]
        [InlineData(0.005, "5.00E-003")]
        [InlineData(0.125, "1.25E-001")]
        [InlineData(0.5, "5.00E-001")]
        [InlineData(0.51, "5.10E-001")]
        [InlineData(0.56789, "5.68E-001")]
        [InlineData(0.84551240822557006, "8.46E-001")]
        [InlineData(1.0, "1.00E+000")]
        [InlineData(505.0, "5.05E+002")]
        [InlineData(506.0, "5.06E+002")]
        [InlineData(545.0, "5.45E+002")]
        [InlineData(545.1, "5.45E+002")]
        [InlineData(555.0, "5.55E+002")]
        [InlineData(65747.125, "6.57E+004")]
        [InlineData(1844674407370955.25, "1.84E+015")]
        public void TestFormatterDouble_E2(double value, string expectedResult) => TestFormatterDouble_Standard(value, "E2", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "4.9407E-324")]
        [InlineData(double.MaxValue, "1.7977E+308")]
        [InlineData(Math.E, "2.7183E+000")]
        [InlineData(Math.PI, "3.1416E+000")]
        [InlineData(0.0, "0.0000E+000")]
        [InlineData(0.0046, "4.6000E-003")]
        [InlineData(0.005, "5.0000E-003")]
        [InlineData(0.125, "1.2500E-001")]
        [InlineData(0.5, "5.0000E-001")]
        [InlineData(0.51, "5.1000E-001")]
        [InlineData(0.56789, "5.6789E-001")]
        [InlineData(0.84551240822557006, "8.4551E-001")]
        [InlineData(1.0, "1.0000E+000")]
        [InlineData(505.0, "5.0500E+002")]
        [InlineData(506.0, "5.0600E+002")]
        [InlineData(545.0, "5.4500E+002")]
        [InlineData(545.1, "5.4510E+002")]
        [InlineData(555.0, "5.5500E+002")]
        [InlineData(65747.125, "6.5747E+004")]
        [InlineData(1844674407370955.25, "1.8447E+015")]
        public void TestFormatterDouble_E4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "E4", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "4.94065645841246544177E-324")]
        [InlineData(double.MaxValue, "1.79769313486231570815E+308")]
        [InlineData(Math.E, "2.71828182845904509080E+000")]
        [InlineData(Math.PI, "3.14159265358979311600E+000")]
        [InlineData(0.0, "0.00000000000000000000E+000")]
        [InlineData(0.0046, "4.59999999999999992228E-003")]
        [InlineData(0.005, "5.00000000000000010408E-003")]
        [InlineData(0.125, "1.25000000000000000000E-001")]
        [InlineData(0.5, "5.00000000000000000000E-001")]
        [InlineData(0.51, "5.10000000000000008882E-001")]
        [InlineData(0.56789, "5.67890000000000005898E-001")]
        [InlineData(0.84551240822557006, "8.45512408225570055720E-001")]
        [InlineData(1.0, "1.00000000000000000000E+000")]
        [InlineData(505.0, "5.05000000000000000000E+002")]
        [InlineData(506.0, "5.06000000000000000000E+002")]
        [InlineData(545.0, "5.45000000000000000000E+002")]
        [InlineData(545.1, "5.45100000000000022737E+002")]
        [InlineData(555.0, "5.55000000000000000000E+002")]
        [InlineData(65747.125, "6.57471250000000000000E+004")]
        [InlineData(1844674407370955.25, "1.84467440737095525000E+015")]
        public void TestFormatterDouble_E20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "E20", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.00")]
        [InlineData(double.MaxValue, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.00")]
        [InlineData(Math.E, "2.72")]
        [InlineData(Math.PI, "3.14")]
        [InlineData(0.0, "0.00")]
        [InlineData(0.0046, "0.00")]
        [InlineData(0.005, "0.01")]
        [InlineData(0.125, "0.12")]
        [InlineData(0.5, "0.50")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.57")]
        [InlineData(0.84551240822557006, "0.85")]
        [InlineData(1.0, "1.00")]
        [InlineData(505.0, "505.00")]
        [InlineData(506.0, "506.00")]
        [InlineData(545.0, "545.00")]
        [InlineData(545.1, "545.10")]
        [InlineData(555.0, "555.00")]
        [InlineData(65747.125, "65747.12")]
        [InlineData(1844674407370955.25, "1844674407370955.25")]
        public void TestFormatterDouble_F(double value, string expectedResult) => TestFormatterDouble_Standard(value, "F", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0")]
        [InlineData(double.MaxValue, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368")]
        [InlineData(Math.E, "3")]
        [InlineData(Math.PI, "3")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0")]
        [InlineData(0.005, "0")]
        [InlineData(0.125, "0")]
        [InlineData(0.5, "0")]
        [InlineData(0.51, "1")]
        [InlineData(0.56789, "1")]
        [InlineData(0.84551240822557006, "1")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65747")]
        [InlineData(1844674407370955.25, "1844674407370955")]
        public void TestFormatterDouble_F0(double value, string expectedResult) => TestFormatterDouble_Standard(value, "F0", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.00")]
        [InlineData(double.MaxValue, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.00")]
        [InlineData(Math.E, "2.72")]
        [InlineData(Math.PI, "3.14")]
        [InlineData(0.0, "0.00")]
        [InlineData(0.0046, "0.00")]
        [InlineData(0.005, "0.01")]
        [InlineData(0.125, "0.12")]
        [InlineData(0.5, "0.50")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.57")]
        [InlineData(0.84551240822557006, "0.85")]
        [InlineData(1.0, "1.00")]
        [InlineData(505.0, "505.00")]
        [InlineData(506.0, "506.00")]
        [InlineData(545.0, "545.00")]
        [InlineData(545.1, "545.10")]
        [InlineData(555.0, "555.00")]
        [InlineData(65747.125, "65747.12")]
        [InlineData(1844674407370955.25, "1844674407370955.25")]
        public void TestFormatterDouble_F2(double value, string expectedResult) => TestFormatterDouble_Standard(value, "F2", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.0000")]
        [InlineData(double.MaxValue, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0000")]
        [InlineData(Math.E, "2.7183")]
        [InlineData(Math.PI, "3.1416")]
        [InlineData(0.0, "0.0000")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.0050")]
        [InlineData(0.125, "0.1250")]
        [InlineData(0.5, "0.5000")]
        [InlineData(0.51, "0.5100")]
        [InlineData(0.56789, "0.5679")]
        [InlineData(0.84551240822557006, "0.8455")]
        [InlineData(1.0, "1.0000")]
        [InlineData(505.0, "505.0000")]
        [InlineData(506.0, "506.0000")]
        [InlineData(545.0, "545.0000")]
        [InlineData(545.1, "545.1000")]
        [InlineData(555.0, "555.0000")]
        [InlineData(65747.125, "65747.1250")]
        [InlineData(1844674407370955.25, "1844674407370955.2500")]
        public void TestFormatterDouble_F4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "F4", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.00000000000000000000")]
        [InlineData(double.MaxValue, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.00000000000000000000")]
        [InlineData(Math.E, "2.71828182845904509080")]
        [InlineData(Math.PI, "3.14159265358979311600")]
        [InlineData(0.0, "0.00000000000000000000")]
        [InlineData(0.0046, "0.00459999999999999992")]
        [InlineData(0.005, "0.00500000000000000010")]
        [InlineData(0.125, "0.12500000000000000000")]
        [InlineData(0.5, "0.50000000000000000000")]
        [InlineData(0.51, "0.51000000000000000888")]
        [InlineData(0.56789, "0.56789000000000000590")]
        [InlineData(0.84551240822557006, "0.84551240822557005572")]
        [InlineData(1.0, "1.00000000000000000000")]
        [InlineData(505.0, "505.00000000000000000000")]
        [InlineData(506.0, "506.00000000000000000000")]
        [InlineData(545.0, "545.00000000000000000000")]
        [InlineData(545.1, "545.10000000000002273737")]
        [InlineData(555.0, "555.00000000000000000000")]
        [InlineData(65747.125, "65747.12500000000000000000")]
        [InlineData(1844674407370955.25, "1844674407370955.25000000000000000000")]
        public void TestFormatterDouble_F20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "F20", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "5E-324")]
        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
        [InlineData(Math.E, "2.718281828459045")]
        [InlineData(Math.PI, "3.141592653589793")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.005")]
        [InlineData(0.125, "0.125")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.56789")]
        [InlineData(0.84551240822557006, "0.8455124082255701")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545.1")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65747.125")]
        [InlineData(1844674407370955.25, "1844674407370955.2")]
        public void TestFormatterDouble_G(double value, string expectedResult) => TestFormatterDouble_Standard(value, "G", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "5E-324")]
        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
        [InlineData(Math.E, "2.718281828459045")]
        [InlineData(Math.PI, "3.141592653589793")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.005")]
        [InlineData(0.125, "0.125")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.56789")]
        [InlineData(0.84551240822557006, "0.8455124082255701")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545.1")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65747.125")]
        [InlineData(1844674407370955.25, "1844674407370955.2")]
        public void TestFormatterDouble_G0(double value, string expectedResult) => TestFormatterDouble_Standard(value, "G0", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "4.9E-324")]
        [InlineData(double.MaxValue, "1.8E+308")]
        [InlineData(Math.E, "2.7")]
        [InlineData(Math.PI, "3.1")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.005")]
        [InlineData(0.125, "0.12")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.57")]
        [InlineData(0.84551240822557006, "0.85")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "5E+02")]
        [InlineData(506.0, "5.1E+02")]
        [InlineData(545.0, "5.4E+02")]
        [InlineData(545.1, "5.5E+02")]
        [InlineData(555.0, "5.6E+02")]
        [InlineData(65747.125, "6.6E+04")]
        [InlineData(1844674407370955.25, "1.8E+15")]
        public void TestFormatterDouble_G2(double value, string expectedResult) => TestFormatterDouble_Standard(value, "G2", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "4.941E-324")]
        [InlineData(double.MaxValue, "1.798E+308")]
        [InlineData(Math.E, "2.718")]
        [InlineData(Math.PI, "3.142")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.005")]
        [InlineData(0.125, "0.125")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.5679")]
        [InlineData(0.84551240822557006, "0.8455")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545.1")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "6.575E+04")]
        [InlineData(1844674407370955.25, "1.845E+15")]
        public void TestFormatterDouble_G4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "G4", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "4.9406564584124654418E-324")]
        [InlineData(double.MaxValue, "1.7976931348623157081E+308")]
        [InlineData(Math.E, "2.7182818284590450908")]
        [InlineData(Math.PI, "3.141592653589793116")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0045999999999999999223")]
        [InlineData(0.005, "0.0050000000000000001041")]
        [InlineData(0.125, "0.125")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51000000000000000888")]
        [InlineData(0.56789, "0.5678900000000000059")]
        [InlineData(0.84551240822557006, "0.84551240822557005572")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545.10000000000002274")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65747.125")]
        [InlineData(1844674407370955.25, "1844674407370955.25")]
        public void TestFormatterDouble_G20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "G20", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.00")]
        [InlineData(double.MaxValue, "179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00")]
        [InlineData(Math.E, "2.72")]
        [InlineData(Math.PI, "3.14")]
        [InlineData(0.0, "0.00")]
        [InlineData(0.0046, "0.00")]
        [InlineData(0.005, "0.01")]
        [InlineData(0.125, "0.12")]
        [InlineData(0.5, "0.50")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.57")]
        [InlineData(0.84551240822557006, "0.85")]
        [InlineData(1.0, "1.00")]
        [InlineData(505.0, "505.00")]
        [InlineData(506.0, "506.00")]
        [InlineData(545.0, "545.00")]
        [InlineData(545.1, "545.10")]
        [InlineData(555.0, "555.00")]
        [InlineData(65747.125, "65,747.12")]
        [InlineData(1844674407370955.25, "1,844,674,407,370,955.25")]
        public void TestFormatterDouble_N(double value, string expectedResult) => TestFormatterDouble_Standard(value, "N", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0")]
        [InlineData(double.MaxValue, "179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368")]
        [InlineData(Math.E, "3")]
        [InlineData(Math.PI, "3")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0")]
        [InlineData(0.005, "0")]
        [InlineData(0.125, "0")]
        [InlineData(0.5, "0")]
        [InlineData(0.51, "1")]
        [InlineData(0.56789, "1")]
        [InlineData(0.84551240822557006, "1")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65,747")]
        [InlineData(1844674407370955.25, "1,844,674,407,370,955")]
        public void TestFormatterDouble_N0(double value, string expectedResult) => TestFormatterDouble_Standard(value, "N0", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.00")]
        [InlineData(double.MaxValue, "179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00")]
        [InlineData(Math.E, "2.72")]
        [InlineData(Math.PI, "3.14")]
        [InlineData(0.0, "0.00")]
        [InlineData(0.0046, "0.00")]
        [InlineData(0.005, "0.01")]
        [InlineData(0.125, "0.12")]
        [InlineData(0.5, "0.50")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.57")]
        [InlineData(0.84551240822557006, "0.85")]
        [InlineData(1.0, "1.00")]
        [InlineData(505.0, "505.00")]
        [InlineData(506.0, "506.00")]
        [InlineData(545.0, "545.00")]
        [InlineData(545.1, "545.10")]
        [InlineData(555.0, "555.00")]
        [InlineData(65747.125, "65,747.12")]
        [InlineData(1844674407370955.25, "1,844,674,407,370,955.25")]
        public void TestFormatterDouble_N2(double value, string expectedResult) => TestFormatterDouble_Standard(value, "N2", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.0000")]
        [InlineData(double.MaxValue, "179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.0000")]
        [InlineData(Math.E, "2.7183")]
        [InlineData(Math.PI, "3.1416")]
        [InlineData(0.0, "0.0000")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.0050")]
        [InlineData(0.125, "0.1250")]
        [InlineData(0.5, "0.5000")]
        [InlineData(0.51, "0.5100")]
        [InlineData(0.56789, "0.5679")]
        [InlineData(0.84551240822557006, "0.8455")]
        [InlineData(1.0, "1.0000")]
        [InlineData(505.0, "505.0000")]
        [InlineData(506.0, "506.0000")]
        [InlineData(545.0, "545.0000")]
        [InlineData(545.1, "545.1000")]
        [InlineData(555.0, "555.0000")]
        [InlineData(65747.125, "65,747.1250")]
        [InlineData(1844674407370955.25, "1,844,674,407,370,955.2500")]
        public void TestFormatterDouble_N4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "N4", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.00000000000000000000")]
        [InlineData(double.MaxValue, "179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00000000000000000000")]
        [InlineData(Math.E, "2.71828182845904509080")]
        [InlineData(Math.PI, "3.14159265358979311600")]
        [InlineData(0.0, "0.00000000000000000000")]
        [InlineData(0.0046, "0.00459999999999999992")]
        [InlineData(0.005, "0.00500000000000000010")]
        [InlineData(0.125, "0.12500000000000000000")]
        [InlineData(0.5, "0.50000000000000000000")]
        [InlineData(0.51, "0.51000000000000000888")]
        [InlineData(0.56789, "0.56789000000000000590")]
        [InlineData(0.84551240822557006, "0.84551240822557005572")]
        [InlineData(1.0, "1.00000000000000000000")]
        [InlineData(505.0, "505.00000000000000000000")]
        [InlineData(506.0, "506.00000000000000000000")]
        [InlineData(545.0, "545.00000000000000000000")]
        [InlineData(545.1, "545.10000000000002273737")]
        [InlineData(555.0, "555.00000000000000000000")]
        [InlineData(65747.125, "65,747.12500000000000000000")]
        [InlineData(1844674407370955.25, "1,844,674,407,370,955.25000000000000000000")]
        public void TestFormatterDouble_N20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "N20", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.00 %")]
        [InlineData(double.MaxValue, "17,976,931,348,623,157,081,452,742,373,170,435,679,807,056,752,584,499,659,891,747,680,315,726,078,002,853,876,058,955,863,276,687,817,154,045,895,351,438,246,423,432,132,688,946,418,276,846,754,670,353,751,698,604,991,057,655,128,207,624,549,009,038,932,894,407,586,850,845,513,394,230,458,323,690,322,294,816,580,855,933,212,334,827,479,782,620,414,472,316,873,817,718,091,929,988,125,040,402,618,412,485,836,800.00 %")]
        [InlineData(Math.E, "271.83 %")]
        [InlineData(Math.PI, "314.16 %")]
        [InlineData(0.0, "0.00 %")]
        [InlineData(0.0046, "0.46 %")]
        [InlineData(0.005, "0.50 %")]
        [InlineData(0.125, "12.50 %")]
        [InlineData(0.5, "50.00 %")]
        [InlineData(0.51, "51.00 %")]
        [InlineData(0.56789, "56.79 %")]
        [InlineData(0.84551240822557006, "84.55 %")]
        [InlineData(1.0, "100.00 %")]
        [InlineData(505.0, "50,500.00 %")]
        [InlineData(506.0, "50,600.00 %")]
        [InlineData(545.0, "54,500.00 %")]
        [InlineData(545.1, "54,510.00 %")]
        [InlineData(555.0, "55,500.00 %")]
        [InlineData(65747.125, "6,574,712.50 %")]
        [InlineData(1844674407370955.25, "184,467,440,737,095,525.00 %")]
        public void TestFormatterDouble_P(double value, string expectedResult) => TestFormatterDouble_Standard(value, "P", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0 %")]
        [InlineData(double.MaxValue, "17,976,931,348,623,157,081,452,742,373,170,435,679,807,056,752,584,499,659,891,747,680,315,726,078,002,853,876,058,955,863,276,687,817,154,045,895,351,438,246,423,432,132,688,946,418,276,846,754,670,353,751,698,604,991,057,655,128,207,624,549,009,038,932,894,407,586,850,845,513,394,230,458,323,690,322,294,816,580,855,933,212,334,827,479,782,620,414,472,316,873,817,718,091,929,988,125,040,402,618,412,485,836,800 %")]
        [InlineData(Math.E, "272 %")]
        [InlineData(Math.PI, "314 %")]
        [InlineData(0.0, "0 %")]
        [InlineData(0.0046, "0 %")]
        [InlineData(0.005, "1 %")]
        [InlineData(0.125, "12 %")]
        [InlineData(0.5, "50 %")]
        [InlineData(0.51, "51 %")]
        [InlineData(0.56789, "57 %")]
        [InlineData(0.84551240822557006, "85 %")]
        [InlineData(1.0, "100 %")]
        [InlineData(505.0, "50,500 %")]
        [InlineData(506.0, "50,600 %")]
        [InlineData(545.0, "54,500 %")]
        [InlineData(545.1, "54,510 %")]
        [InlineData(555.0, "55,500 %")]
        [InlineData(65747.125, "6,574,712 %")]
        [InlineData(1844674407370955.25, "184,467,440,737,095,525 %")]
        public void TestFormatterDouble_P0(double value, string expectedResult) => TestFormatterDouble_Standard(value, "P0", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.00 %")]
        [InlineData(double.MaxValue, "17,976,931,348,623,157,081,452,742,373,170,435,679,807,056,752,584,499,659,891,747,680,315,726,078,002,853,876,058,955,863,276,687,817,154,045,895,351,438,246,423,432,132,688,946,418,276,846,754,670,353,751,698,604,991,057,655,128,207,624,549,009,038,932,894,407,586,850,845,513,394,230,458,323,690,322,294,816,580,855,933,212,334,827,479,782,620,414,472,316,873,817,718,091,929,988,125,040,402,618,412,485,836,800.00 %")]
        [InlineData(Math.E, "271.83 %")]
        [InlineData(Math.PI, "314.16 %")]
        [InlineData(0.0, "0.00 %")]
        [InlineData(0.0046, "0.46 %")]
        [InlineData(0.005, "0.50 %")]
        [InlineData(0.125, "12.50 %")]
        [InlineData(0.5, "50.00 %")]
        [InlineData(0.51, "51.00 %")]
        [InlineData(0.56789, "56.79 %")]
        [InlineData(0.84551240822557006, "84.55 %")]
        [InlineData(1.0, "100.00 %")]
        [InlineData(505.0, "50,500.00 %")]
        [InlineData(506.0, "50,600.00 %")]
        [InlineData(545.0, "54,500.00 %")]
        [InlineData(545.1, "54,510.00 %")]
        [InlineData(555.0, "55,500.00 %")]
        [InlineData(65747.125, "6,574,712.50 %")]
        [InlineData(1844674407370955.25, "184,467,440,737,095,525.00 %")]
        public void TestFormatterDouble_P2(double value, string expectedResult) => TestFormatterDouble_Standard(value, "P2", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.0000 %")]
        [InlineData(double.MaxValue, "17,976,931,348,623,157,081,452,742,373,170,435,679,807,056,752,584,499,659,891,747,680,315,726,078,002,853,876,058,955,863,276,687,817,154,045,895,351,438,246,423,432,132,688,946,418,276,846,754,670,353,751,698,604,991,057,655,128,207,624,549,009,038,932,894,407,586,850,845,513,394,230,458,323,690,322,294,816,580,855,933,212,334,827,479,782,620,414,472,316,873,817,718,091,929,988,125,040,402,618,412,485,836,800.0000 %")]
        [InlineData(Math.E, "271.8282 %")]
        [InlineData(Math.PI, "314.1593 %")]
        [InlineData(0.0, "0.0000 %")]
        [InlineData(0.0046, "0.4600 %")]
        [InlineData(0.005, "0.5000 %")]
        [InlineData(0.125, "12.5000 %")]
        [InlineData(0.5, "50.0000 %")]
        [InlineData(0.51, "51.0000 %")]
        [InlineData(0.56789, "56.7890 %")]
        [InlineData(0.84551240822557006, "84.5512 %")]
        [InlineData(1.0, "100.0000 %")]
        [InlineData(505.0, "50,500.0000 %")]
        [InlineData(506.0, "50,600.0000 %")]
        [InlineData(545.0, "54,500.0000 %")]
        [InlineData(545.1, "54,510.0000 %")]
        [InlineData(555.0, "55,500.0000 %")]
        [InlineData(65747.125, "6,574,712.5000 %")]
        [InlineData(1844674407370955.25, "184,467,440,737,095,525.0000 %")]
        public void TestFormatterDouble_P4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "P4", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "0.00000000000000000000 %")]
        [InlineData(double.MaxValue, "17,976,931,348,623,157,081,452,742,373,170,435,679,807,056,752,584,499,659,891,747,680,315,726,078,002,853,876,058,955,863,276,687,817,154,045,895,351,438,246,423,432,132,688,946,418,276,846,754,670,353,751,698,604,991,057,655,128,207,624,549,009,038,932,894,407,586,850,845,513,394,230,458,323,690,322,294,816,580,855,933,212,334,827,479,782,620,414,472,316,873,817,718,091,929,988,125,040,402,618,412,485,836,800.00000000000000000000 %")]
        [InlineData(Math.E, "271.82818284590450907956 %")]
        [InlineData(Math.PI, "314.15926535897931159980 %")]
        [InlineData(0.0, "0.00000000000000000000 %")]
        [InlineData(0.0046, "0.45999999999999999223 %")]
        [InlineData(0.005, "0.50000000000000001041 %")]
        [InlineData(0.125, "12.50000000000000000000 %")]
        [InlineData(0.5, "50.00000000000000000000 %")]
        [InlineData(0.51, "51.00000000000000088818 %")]
        [InlineData(0.56789, "56.78900000000000058975 %")]
        [InlineData(0.84551240822557006, "84.55124082255700557198 %")]
        [InlineData(1.0, "100.00000000000000000000 %")]
        [InlineData(505.0, "50,500.00000000000000000000 %")]
        [InlineData(506.0, "50,600.00000000000000000000 %")]
        [InlineData(545.0, "54,500.00000000000000000000 %")]
        [InlineData(545.1, "54,510.00000000000227373675 %")]
        [InlineData(555.0, "55,500.00000000000000000000 %")]
        [InlineData(65747.125, "6,574,712.50000000000000000000 %")]
        [InlineData(1844674407370955.25, "184,467,440,737,095,525.00000000000000000000 %")]
        public void TestFormatterDouble_P20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "P20", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "5E-324")]
        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
        [InlineData(Math.E, "2.718281828459045")]
        [InlineData(Math.PI, "3.141592653589793")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.005")]
        [InlineData(0.125, "0.125")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.56789")]
        [InlineData(0.84551240822557006, "0.8455124082255701")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545.1")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65747.125")]
        [InlineData(1844674407370955.25, "1844674407370955.2")]
        public void TestFormatterDouble_R(double value, string expectedResult) => TestFormatterDouble_Standard(value, "R", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "5E-324")]
        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
        [InlineData(Math.E, "2.718281828459045")]
        [InlineData(Math.PI, "3.141592653589793")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.005")]
        [InlineData(0.125, "0.125")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.56789")]
        [InlineData(0.84551240822557006, "0.8455124082255701")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545.1")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65747.125")]
        [InlineData(1844674407370955.25, "1844674407370955.2")]
        public void TestFormatterDouble_R0(double value, string expectedResult) => TestFormatterDouble_Standard(value, "R0", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "5E-324")]
        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
        [InlineData(Math.E, "2.718281828459045")]
        [InlineData(Math.PI, "3.141592653589793")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.005")]
        [InlineData(0.125, "0.125")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.56789")]
        [InlineData(0.84551240822557006, "0.8455124082255701")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545.1")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65747.125")]
        [InlineData(1844674407370955.25, "1844674407370955.2")]
        public void TestFormatterDouble_R2(double value, string expectedResult) => TestFormatterDouble_Standard(value, "R2", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "5E-324")]
        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
        [InlineData(Math.E, "2.718281828459045")]
        [InlineData(Math.PI, "3.141592653589793")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.005")]
        [InlineData(0.125, "0.125")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.56789")]
        [InlineData(0.84551240822557006, "0.8455124082255701")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545.1")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65747.125")]
        [InlineData(1844674407370955.25, "1844674407370955.2")]
        public void TestFormatterDouble_R4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "R4", expectedResult);

        [Theory]
        [InlineData(double.Epsilon, "5E-324")]
        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
        [InlineData(Math.E, "2.718281828459045")]
        [InlineData(Math.PI, "3.141592653589793")]
        [InlineData(0.0, "0")]
        [InlineData(0.0046, "0.0046")]
        [InlineData(0.005, "0.005")]
        [InlineData(0.125, "0.125")]
        [InlineData(0.5, "0.5")]
        [InlineData(0.51, "0.51")]
        [InlineData(0.56789, "0.56789")]
        [InlineData(0.84551240822557006, "0.8455124082255701")]
        [InlineData(1.0, "1")]
        [InlineData(505.0, "505")]
        [InlineData(506.0, "506")]
        [InlineData(545.0, "545")]
        [InlineData(545.1, "545.1")]
        [InlineData(555.0, "555")]
        [InlineData(65747.125, "65747.125")]
        [InlineData(1844674407370955.25, "1844674407370955.2")]
        public void TestFormatterDouble_R20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "R20", expectedResult);

        public static IEnumerable<object[]> TestFormatterDouble_InvalidMemberData =>
            from value in new[] { double.Epsilon, double.MaxValue, Math.E, Math.PI, 0.0, 0.84551240822557006, 1.0, 1844674407370955.25 }
            from format in new[] { "D", "D4", "D20", "X", "X4", "X20" }
            select new object[] { value, format };

        [Theory]
        [MemberData(nameof(TestFormatterDouble_InvalidMemberData))]
        public void TestFormatterDouble_Invalid(double value, string format) => Assert.Throws<FormatException>(() => InvariantToStringDouble(value, format));

        protected void TestFormatterDouble_Standard(double value, string format, string expectedResult)
        {
            string actualResult = InvariantToStringDouble(value, format);
            Assert.Equal(expectedResult, actualResult);
        }

        [Theory]
        [InlineData(float.Epsilon, "\u00A40.00")]
        [InlineData(float.MaxValue, "\u00A4340,282,346,638,528,859,811,704,183,484,516,925,440.00")]
        [InlineData(MathF.E, "\u00A42.72")]
        [InlineData(MathF.PI, "\u00A43.14")]
        [InlineData(0.0f, "\u00A40.00")]
        [InlineData(0.0046f, "\u00A40.00")]
        [InlineData(0.005f, "\u00A40.00")]
        [InlineData(0.125f, "\u00A40.12")]
        [InlineData(0.5f, "\u00A40.50")]
        [InlineData(0.51f, "\u00A40.51")]
        [InlineData(0.56789f, "\u00A40.57")]
        [InlineData(0.845512390f, "\u00A40.85")]
        [InlineData(1.0f, "\u00A41.00")]
        [InlineData(505.0f, "\u00A4505.00")]
        [InlineData(506.0f, "\u00A4506.00")]
        [InlineData(545.0f, "\u00A4545.00")]
        [InlineData(545.1f, "\u00A4545.10")]
        [InlineData(555.0f, "\u00A4555.00")]
        [InlineData(65747.125f, "\u00A465,747.12")]
        [InlineData(429496.72f, "\u00A4429,496.72")]
        public void TestFormatterSingle_C(float value, string expectedResult) => TestFormatterSingle_Standard(value, "C", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "\u00A40")]
        [InlineData(float.MaxValue, "\u00A4340,282,346,638,528,859,811,704,183,484,516,925,440")]
        [InlineData(MathF.E, "\u00A43")]
        [InlineData(MathF.PI, "\u00A43")]
        [InlineData(0.0f, "\u00A40")]
        [InlineData(0.0046f, "\u00A40")]
        [InlineData(0.005f, "\u00A40")]
        [InlineData(0.125f, "\u00A40")]
        [InlineData(0.5f, "\u00A40")]
        [InlineData(0.51f, "\u00A41")]
        [InlineData(0.56789f, "\u00A41")]
        [InlineData(0.845512390f, "\u00A41")]
        [InlineData(1.0f, "\u00A41")]
        [InlineData(505.0f, "\u00A4505")]
        [InlineData(506.0f, "\u00A4506")]
        [InlineData(545.0f, "\u00A4545")]
        [InlineData(545.1f, "\u00A4545")]
        [InlineData(555.0f, "\u00A4555")]
        [InlineData(65747.125f, "\u00A465,747")]
        [InlineData(429496.72f, "\u00A4429,497")]
        public void TestFormatterSingle_C0(float value, string expectedResult) => TestFormatterSingle_Standard(value, "C0", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "\u00A40.00")]
        [InlineData(float.MaxValue, "\u00A4340,282,346,638,528,859,811,704,183,484,516,925,440.00")]
        [InlineData(MathF.E, "\u00A42.72")]
        [InlineData(MathF.PI, "\u00A43.14")]
        [InlineData(0.0f, "\u00A40.00")]
        [InlineData(0.0046f, "\u00A40.00")]
        [InlineData(0.005f, "\u00A40.00")]
        [InlineData(0.125f, "\u00A40.12")]
        [InlineData(0.5f, "\u00A40.50")]
        [InlineData(0.51f, "\u00A40.51")]
        [InlineData(0.56789f, "\u00A40.57")]
        [InlineData(0.845512390f, "\u00A40.85")]
        [InlineData(1.0f, "\u00A41.00")]
        [InlineData(505.0f, "\u00A4505.00")]
        [InlineData(506.0f, "\u00A4506.00")]
        [InlineData(545.0f, "\u00A4545.00")]
        [InlineData(545.1f, "\u00A4545.10")]
        [InlineData(555.0f, "\u00A4555.00")]
        [InlineData(65747.125f, "\u00A465,747.12")]
        [InlineData(429496.72f, "\u00A4429,496.72")]
        public void TestFormatterSingle_C2(float value, string expectedResult) => TestFormatterSingle_Standard(value, "C2", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "\u00A40.0000")]
        [InlineData(float.MaxValue, "\u00A4340,282,346,638,528,859,811,704,183,484,516,925,440.0000")]
        [InlineData(MathF.E, "\u00A42.7183")]
        [InlineData(MathF.PI, "\u00A43.1416")]
        [InlineData(0.0f, "\u00A40.0000")]
        [InlineData(0.0046f, "\u00A40.0046")]
        [InlineData(0.005f, "\u00A40.0050")]
        [InlineData(0.125f, "\u00A40.1250")]
        [InlineData(0.5f, "\u00A40.5000")]
        [InlineData(0.51f, "\u00A40.5100")]
        [InlineData(0.56789f, "\u00A40.5679")]
        [InlineData(0.845512390f, "\u00A40.8455")]
        [InlineData(1.0f, "\u00A41.0000")]
        [InlineData(505.0f, "\u00A4505.0000")]
        [InlineData(506.0f, "\u00A4506.0000")]
        [InlineData(545.0f, "\u00A4545.0000")]
        [InlineData(545.1f, "\u00A4545.1000")]
        [InlineData(555.0f, "\u00A4555.0000")]
        [InlineData(65747.125f, "\u00A465,747.1250")]
        [InlineData(429496.72f, "\u00A4429,496.7188")]
        public void TestFormatterSingle_C4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "C4", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "\u00A40.00000000000000000000")]
        [InlineData(float.MaxValue, "\u00A4340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000000000000")]
        [InlineData(MathF.E, "\u00A42.71828174591064453125")]
        [InlineData(MathF.PI, "\u00A43.14159274101257324219")]
        [InlineData(0.0f, "\u00A40.00000000000000000000")]
        [InlineData(0.0046f, "\u00A40.00460000010207295418")]
        [InlineData(0.005f, "\u00A40.00499999988824129105")]
        [InlineData(0.125f, "\u00A40.12500000000000000000")]
        [InlineData(0.5f, "\u00A40.50000000000000000000")]
        [InlineData(0.51f, "\u00A40.50999999046325683594")]
        [InlineData(0.56789f, "\u00A40.56788998842239379883")]
        [InlineData(0.845512390f, "\u00A40.84551239013671875000")]
        [InlineData(1.0f, "\u00A41.00000000000000000000")]
        [InlineData(505.0f, "\u00A4505.00000000000000000000")]
        [InlineData(506.0f, "\u00A4506.00000000000000000000")]
        [InlineData(545.0f, "\u00A4545.00000000000000000000")]
        [InlineData(545.1f, "\u00A4545.09997558593750000000")]
        [InlineData(555.0f, "\u00A4555.00000000000000000000")]
        [InlineData(65747.125f, "\u00A465,747.12500000000000000000")]
        [InlineData(429496.72f, "\u00A4429,496.71875000000000000000")]
        public void TestFormatterSingle_C20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "C20", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1.401298E-045")]
        [InlineData(float.MaxValue, "3.402823E+038")]
        [InlineData(MathF.E, "2.718282E+000")]
        [InlineData(MathF.PI, "3.141593E+000")]
        [InlineData(0.0f, "0.000000E+000")]
        [InlineData(0.0046f, "4.600000E-003")]
        [InlineData(0.005f, "5.000000E-003")]
        [InlineData(0.125f, "1.250000E-001")]
        [InlineData(0.5f, "5.000000E-001")]
        [InlineData(0.51f, "5.100000E-001")]
        [InlineData(0.56789f, "5.678900E-001")]
        [InlineData(0.845512390f, "8.455124E-001")]
        [InlineData(1.0f, "1.000000E+000")]
        [InlineData(505.0f, "5.050000E+002")]
        [InlineData(506.0f, "5.060000E+002")]
        [InlineData(545.0f, "5.450000E+002")]
        [InlineData(545.1f, "5.451000E+002")]
        [InlineData(555.0f, "5.550000E+002")]
        [InlineData(65747.125f, "6.574712E+004")]
        [InlineData(429496.72f, "4.294967E+005")]
        public void TestFormatterSingle_E(float value, string expectedResult) => TestFormatterSingle_Standard(value, "E", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1E-045")]
        [InlineData(float.MaxValue, "3E+038")]
        [InlineData(MathF.E, "3E+000")]
        [InlineData(MathF.PI, "3E+000")]
        [InlineData(0.0f, "0E+000")]
        [InlineData(0.0046f, "5E-003")]
        [InlineData(0.005f, "5E-003")]
        [InlineData(0.125f, "1E-001")]
        [InlineData(0.5f, "5E-001")]
        [InlineData(0.51f, "5E-001")]
        [InlineData(0.56789f, "6E-001")]
        [InlineData(0.845512390f, "8E-001")]
        [InlineData(1.0f, "1E+000")]
        [InlineData(505.0f, "5E+002")]
        [InlineData(506.0f, "5E+002")]
        [InlineData(545.0f, "5E+002")]
        [InlineData(545.1f, "5E+002")]
        [InlineData(555.0f, "6E+002")]
        [InlineData(65747.125f, "7E+004")]
        [InlineData(429496.72f, "4E+005")]
        public void TestFormatterSingle_E0(float value, string expectedResult) => TestFormatterSingle_Standard(value, "E0", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1.40E-045")]
        [InlineData(float.MaxValue, "3.40E+038")]
        [InlineData(MathF.E, "2.72E+000")]
        [InlineData(MathF.PI, "3.14E+000")]
        [InlineData(0.0f, "0.00E+000")]
        [InlineData(0.0046f, "4.60E-003")]
        [InlineData(0.005f, "5.00E-003")]
        [InlineData(0.125f, "1.25E-001")]
        [InlineData(0.5f, "5.00E-001")]
        [InlineData(0.51f, "5.10E-001")]
        [InlineData(0.56789f, "5.68E-001")]
        [InlineData(0.845512390f, "8.46E-001")]
        [InlineData(1.0f, "1.00E+000")]
        [InlineData(505.0f, "5.05E+002")]
        [InlineData(506.0f, "5.06E+002")]
        [InlineData(545.0f, "5.45E+002")]
        [InlineData(545.1f, "5.45E+002")]
        [InlineData(555.0f, "5.55E+002")]
        [InlineData(65747.125f, "6.57E+004")]
        [InlineData(429496.72f, "4.29E+005")]
        public void TestFormatterSingle_E2(float value, string expectedResult) => TestFormatterSingle_Standard(value, "E2", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1.4013E-045")]
        [InlineData(float.MaxValue, "3.4028E+038")]
        [InlineData(MathF.E, "2.7183E+000")]
        [InlineData(MathF.PI, "3.1416E+000")]
        [InlineData(0.0f, "0.0000E+000")]
        [InlineData(0.0046f, "4.6000E-003")]
        [InlineData(0.005f, "5.0000E-003")]
        [InlineData(0.125f, "1.2500E-001")]
        [InlineData(0.5f, "5.0000E-001")]
        [InlineData(0.51f, "5.1000E-001")]
        [InlineData(0.56789f, "5.6789E-001")]
        [InlineData(0.845512390f, "8.4551E-001")]
        [InlineData(1.0f, "1.0000E+000")]
        [InlineData(505.0f, "5.0500E+002")]
        [InlineData(506.0f, "5.0600E+002")]
        [InlineData(545.0f, "5.4500E+002")]
        [InlineData(545.1f, "5.4510E+002")]
        [InlineData(555.0f, "5.5500E+002")]
        [InlineData(65747.125f, "6.5747E+004")]
        [InlineData(429496.72f, "4.2950E+005")]
        public void TestFormatterSingle_E4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "E4", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1.40129846432481707092E-045")]
        [InlineData(float.MaxValue, "3.40282346638528859812E+038")]
        [InlineData(MathF.E, "2.71828174591064453125E+000")]
        [InlineData(MathF.PI, "3.14159274101257324219E+000")]
        [InlineData(0.0f, "0.00000000000000000000E+000")]
        [InlineData(0.0046f, "4.60000010207295417786E-003")]
        [InlineData(0.005f, "4.99999988824129104614E-003")]
        [InlineData(0.125f, "1.25000000000000000000E-001")]
        [InlineData(0.5f, "5.00000000000000000000E-001")]
        [InlineData(0.51f, "5.09999990463256835938E-001")]
        [InlineData(0.56789f, "5.67889988422393798828E-001")]
        [InlineData(0.845512390f, "8.45512390136718750000E-001")]
        [InlineData(1.0f, "1.00000000000000000000E+000")]
        [InlineData(505.0f, "5.05000000000000000000E+002")]
        [InlineData(506.0f, "5.06000000000000000000E+002")]
        [InlineData(545.0f, "5.45000000000000000000E+002")]
        [InlineData(545.1f, "5.45099975585937500000E+002")]
        [InlineData(555.0f, "5.55000000000000000000E+002")]
        [InlineData(65747.125f, "6.57471250000000000000E+004")]
        [InlineData(429496.72f, "4.29496718750000000000E+005")]
        public void TestFormatterSingle_E20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "E20", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.00")]
        [InlineData(float.MaxValue, "340282346638528859811704183484516925440.00")]
        [InlineData(MathF.E, "2.72")]
        [InlineData(MathF.PI, "3.14")]
        [InlineData(0.0f, "0.00")]
        [InlineData(0.0046f, "0.00")]
        [InlineData(0.005f, "0.00")]
        [InlineData(0.125f, "0.12")]
        [InlineData(0.5f, "0.50")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.57")]
        [InlineData(0.845512390f, "0.85")]
        [InlineData(1.0f, "1.00")]
        [InlineData(505.0f, "505.00")]
        [InlineData(506.0f, "506.00")]
        [InlineData(545.0f, "545.00")]
        [InlineData(545.1f, "545.10")]
        [InlineData(555.0f, "555.00")]
        [InlineData(65747.125f, "65747.12")]
        [InlineData(429496.72f, "429496.72")]
        public void TestFormatterSingle_F(float value, string expectedResult) => TestFormatterSingle_Standard(value, "F", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0")]
        [InlineData(float.MaxValue, "340282346638528859811704183484516925440")]
        [InlineData(MathF.E, "3")]
        [InlineData(MathF.PI, "3")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0")]
        [InlineData(0.005f, "0")]
        [InlineData(0.125f, "0")]
        [InlineData(0.5f, "0")]
        [InlineData(0.51f, "1")]
        [InlineData(0.56789f, "1")]
        [InlineData(0.845512390f, "1")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65747")]
        [InlineData(429496.72f, "429497")]
        public void TestFormatterSingle_F0(float value, string expectedResult) => TestFormatterSingle_Standard(value, "F0", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.00")]
        [InlineData(float.MaxValue, "340282346638528859811704183484516925440.00")]
        [InlineData(MathF.E, "2.72")]
        [InlineData(MathF.PI, "3.14")]
        [InlineData(0.0f, "0.00")]
        [InlineData(0.0046f, "0.00")]
        [InlineData(0.005f, "0.00")]
        [InlineData(0.125f, "0.12")]
        [InlineData(0.5f, "0.50")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.57")]
        [InlineData(0.845512390f, "0.85")]
        [InlineData(1.0f, "1.00")]
        [InlineData(505.0f, "505.00")]
        [InlineData(506.0f, "506.00")]
        [InlineData(545.0f, "545.00")]
        [InlineData(545.1f, "545.10")]
        [InlineData(555.0f, "555.00")]
        [InlineData(65747.125f, "65747.12")]
        [InlineData(429496.72f, "429496.72")]
        public void TestFormatterSingle_F2(float value, string expectedResult) => TestFormatterSingle_Standard(value, "F2", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.0000")]
        [InlineData(float.MaxValue, "340282346638528859811704183484516925440.0000")]
        [InlineData(MathF.E, "2.7183")]
        [InlineData(MathF.PI, "3.1416")]
        [InlineData(0.0f, "0.0000")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.0050")]
        [InlineData(0.125f, "0.1250")]
        [InlineData(0.5f, "0.5000")]
        [InlineData(0.51f, "0.5100")]
        [InlineData(0.56789f, "0.5679")]
        [InlineData(0.845512390f, "0.8455")]
        [InlineData(1.0f, "1.0000")]
        [InlineData(505.0f, "505.0000")]
        [InlineData(506.0f, "506.0000")]
        [InlineData(545.0f, "545.0000")]
        [InlineData(545.1f, "545.1000")]
        [InlineData(555.0f, "555.0000")]
        [InlineData(65747.125f, "65747.1250")]
        [InlineData(429496.72f, "429496.7188")]
        public void TestFormatterSingle_F4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "F4", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.00000000000000000000")]
        [InlineData(float.MaxValue, "340282346638528859811704183484516925440.00000000000000000000")]
        [InlineData(MathF.E, "2.71828174591064453125")]
        [InlineData(MathF.PI, "3.14159274101257324219")]
        [InlineData(0.0f, "0.00000000000000000000")]
        [InlineData(0.0046f, "0.00460000010207295418")]
        [InlineData(0.005f, "0.00499999988824129105")]
        [InlineData(0.125f, "0.12500000000000000000")]
        [InlineData(0.5f, "0.50000000000000000000")]
        [InlineData(0.51f, "0.50999999046325683594")]
        [InlineData(0.56789f, "0.56788998842239379883")]
        [InlineData(0.845512390f, "0.84551239013671875000")]
        [InlineData(1.0f, "1.00000000000000000000")]
        [InlineData(505.0f, "505.00000000000000000000")]
        [InlineData(506.0f, "506.00000000000000000000")]
        [InlineData(545.0f, "545.00000000000000000000")]
        [InlineData(545.1f, "545.09997558593750000000")]
        [InlineData(555.0f, "555.00000000000000000000")]
        [InlineData(65747.125f, "65747.12500000000000000000")]
        [InlineData(429496.72f, "429496.71875000000000000000")]
        public void TestFormatterSingle_F20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "F20", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1E-45")]
        [InlineData(float.MaxValue, "3.4028235E+38")]
        [InlineData(MathF.E, "2.7182817")]
        [InlineData(MathF.PI, "3.1415927")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.005")]
        [InlineData(0.125f, "0.125")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.56789")]
        [InlineData(0.845512390f, "0.8455124")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545.1")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65747.125")]
        [InlineData(429496.72f, "429496.72")]
        public void TestFormatterSingle_G(float value, string expectedResult) => TestFormatterSingle_Standard(value, "G", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1E-45")]
        [InlineData(float.MaxValue, "3.4028235E+38")]
        [InlineData(MathF.E, "2.7182817")]
        [InlineData(MathF.PI, "3.1415927")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.005")]
        [InlineData(0.125f, "0.125")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.56789")]
        [InlineData(0.845512390f, "0.8455124")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545.1")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65747.125")]
        [InlineData(429496.72f, "429496.72")]
        public void TestFormatterSingle_G0(float value, string expectedResult) => TestFormatterSingle_Standard(value, "G0", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1.4E-45")]
        [InlineData(float.MaxValue, "3.4E+38")]
        [InlineData(MathF.E, "2.7")]
        [InlineData(MathF.PI, "3.1")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.005")]
        [InlineData(0.125f, "0.12")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.57")]
        [InlineData(0.845512390f, "0.85")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "5E+02")]
        [InlineData(506.0f, "5.1E+02")]
        [InlineData(545.0f, "5.4E+02")]
        [InlineData(545.1f, "5.5E+02")]
        [InlineData(555.0f, "5.6E+02")]
        [InlineData(65747.125f, "6.6E+04")]
        [InlineData(429496.72f, "4.3E+05")]
        public void TestFormatterSingle_G2(float value, string expectedResult) => TestFormatterSingle_Standard(value, "G2", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1.401E-45")]
        [InlineData(float.MaxValue, "3.403E+38")]
        [InlineData(MathF.E, "2.718")]
        [InlineData(MathF.PI, "3.142")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.005")]
        [InlineData(0.125f, "0.125")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.5679")]
        [InlineData(0.845512390f, "0.8455")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545.1")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "6.575E+04")]
        [InlineData(429496.72f, "4.295E+05")]
        public void TestFormatterSingle_G4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "G4", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1.4012984643248170709E-45")]
        [InlineData(float.MaxValue, "3.4028234663852885981E+38")]
        [InlineData(MathF.E, "2.7182817459106445312")]
        [InlineData(MathF.PI, "3.1415927410125732422")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046000001020729541779")]
        [InlineData(0.005f, "0.0049999998882412910461")]
        [InlineData(0.125f, "0.125")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.50999999046325683594")]
        [InlineData(0.56789f, "0.56788998842239379883")]
        [InlineData(0.845512390f, "0.84551239013671875")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545.0999755859375")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65747.125")]
        [InlineData(429496.72f, "429496.71875")]
        public void TestFormatterSingle_G20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "G20", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.00")]
        [InlineData(float.MaxValue, "340,282,346,638,528,859,811,704,183,484,516,925,440.00")]
        [InlineData(MathF.E, "2.72")]
        [InlineData(MathF.PI, "3.14")]
        [InlineData(0.0f, "0.00")]
        [InlineData(0.0046f, "0.00")]
        [InlineData(0.005f, "0.00")]
        [InlineData(0.125f, "0.12")]
        [InlineData(0.5f, "0.50")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.57")]
        [InlineData(0.845512390f, "0.85")]
        [InlineData(1.0f, "1.00")]
        [InlineData(505.0f, "505.00")]
        [InlineData(506.0f, "506.00")]
        [InlineData(545.0f, "545.00")]
        [InlineData(545.1f, "545.10")]
        [InlineData(555.0f, "555.00")]
        [InlineData(65747.125f, "65,747.12")]
        [InlineData(429496.72f, "429,496.72")]
        public void TestFormatterSingle_N(float value, string expectedResult) => TestFormatterSingle_Standard(value, "N", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0")]
        [InlineData(float.MaxValue, "340,282,346,638,528,859,811,704,183,484,516,925,440")]
        [InlineData(MathF.E, "3")]
        [InlineData(MathF.PI, "3")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0")]
        [InlineData(0.005f, "0")]
        [InlineData(0.125f, "0")]
        [InlineData(0.5f, "0")]
        [InlineData(0.51f, "1")]
        [InlineData(0.56789f, "1")]
        [InlineData(0.845512390f, "1")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65,747")]
        [InlineData(429496.72f, "429,497")]
        public void TestFormatterSingle_N0(float value, string expectedResult) => TestFormatterSingle_Standard(value, "N0", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.00")]
        [InlineData(float.MaxValue, "340,282,346,638,528,859,811,704,183,484,516,925,440.00")]
        [InlineData(MathF.E, "2.72")]
        [InlineData(MathF.PI, "3.14")]
        [InlineData(0.0f, "0.00")]
        [InlineData(0.0046f, "0.00")]
        [InlineData(0.005f, "0.00")]
        [InlineData(0.125f, "0.12")]
        [InlineData(0.5f, "0.50")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.57")]
        [InlineData(0.845512390f, "0.85")]
        [InlineData(1.0f, "1.00")]
        [InlineData(505.0f, "505.00")]
        [InlineData(506.0f, "506.00")]
        [InlineData(545.0f, "545.00")]
        [InlineData(545.1f, "545.10")]
        [InlineData(555.0f, "555.00")]
        [InlineData(65747.125f, "65,747.12")]
        [InlineData(429496.72f, "429,496.72")]
        public void TestFormatterSingle_N2(float value, string expectedResult) => TestFormatterSingle_Standard(value, "N2", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.0000")]
        [InlineData(float.MaxValue, "340,282,346,638,528,859,811,704,183,484,516,925,440.0000")]
        [InlineData(MathF.E, "2.7183")]
        [InlineData(MathF.PI, "3.1416")]
        [InlineData(0.0f, "0.0000")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.0050")]
        [InlineData(0.125f, "0.1250")]
        [InlineData(0.5f, "0.5000")]
        [InlineData(0.51f, "0.5100")]
        [InlineData(0.56789f, "0.5679")]
        [InlineData(0.845512390f, "0.8455")]
        [InlineData(1.0f, "1.0000")]
        [InlineData(505.0f, "505.0000")]
        [InlineData(506.0f, "506.0000")]
        [InlineData(545.0f, "545.0000")]
        [InlineData(545.1f, "545.1000")]
        [InlineData(555.0f, "555.0000")]
        [InlineData(65747.125f, "65,747.1250")]
        [InlineData(429496.72f, "429,496.7188")]
        public void TestFormatterSingle_N4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "N4", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.00000000000000000000")]
        [InlineData(float.MaxValue, "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000000000000")]
        [InlineData(MathF.E, "2.71828174591064453125")]
        [InlineData(MathF.PI, "3.14159274101257324219")]
        [InlineData(0.0f, "0.00000000000000000000")]
        [InlineData(0.0046f, "0.00460000010207295418")]
        [InlineData(0.005f, "0.00499999988824129105")]
        [InlineData(0.125f, "0.12500000000000000000")]
        [InlineData(0.5f, "0.50000000000000000000")]
        [InlineData(0.51f, "0.50999999046325683594")]
        [InlineData(0.56789f, "0.56788998842239379883")]
        [InlineData(0.845512390f, "0.84551239013671875000")]
        [InlineData(1.0f, "1.00000000000000000000")]
        [InlineData(505.0f, "505.00000000000000000000")]
        [InlineData(506.0f, "506.00000000000000000000")]
        [InlineData(545.0f, "545.00000000000000000000")]
        [InlineData(545.1f, "545.09997558593750000000")]
        [InlineData(555.0f, "555.00000000000000000000")]
        [InlineData(65747.125f, "65,747.12500000000000000000")]
        [InlineData(429496.72f, "429,496.71875000000000000000")]
        public void TestFormatterSingle_N20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "N20", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.00 %")]
        [InlineData(float.MaxValue, "34,028,234,663,852,885,981,170,418,348,451,692,544,000.00 %")]
        [InlineData(MathF.E, "271.83 %")]
        [InlineData(MathF.PI, "314.16 %")]
        [InlineData(0.0f, "0.00 %")]
        [InlineData(0.0046f, "0.46 %")]
        [InlineData(0.005f, "0.50 %")]
        [InlineData(0.125f, "12.50 %")]
        [InlineData(0.5f, "50.00 %")]
        [InlineData(0.51f, "51.00 %")]
        [InlineData(0.56789f, "56.79 %")]
        [InlineData(0.845512390f, "84.55 %")]
        [InlineData(1.0f, "100.00 %")]
        [InlineData(505.0f, "50,500.00 %")]
        [InlineData(506.0f, "50,600.00 %")]
        [InlineData(545.0f, "54,500.00 %")]
        [InlineData(545.1f, "54,510.00 %")]
        [InlineData(555.0f, "55,500.00 %")]
        [InlineData(65747.125f, "6,574,712.50 %")]
        [InlineData(429496.72f, "42,949,671.88 %")]
        public void TestFormatterSingle_P(float value, string expectedResult) => TestFormatterSingle_Standard(value, "P", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0 %")]
        [InlineData(float.MaxValue, "34,028,234,663,852,885,981,170,418,348,451,692,544,000 %")]
        [InlineData(MathF.E, "272 %")]
        [InlineData(MathF.PI, "314 %")]
        [InlineData(0.0f, "0 %")]
        [InlineData(0.0046f, "0 %")]
        [InlineData(0.005f, "0 %")]
        [InlineData(0.125f, "12 %")]
        [InlineData(0.5f, "50 %")]
        [InlineData(0.51f, "51 %")]
        [InlineData(0.56789f, "57 %")]
        [InlineData(0.845512390f, "85 %")]
        [InlineData(1.0f, "100 %")]
        [InlineData(505.0f, "50,500 %")]
        [InlineData(506.0f, "50,600 %")]
        [InlineData(545.0f, "54,500 %")]
        [InlineData(545.1f, "54,510 %")]
        [InlineData(555.0f, "55,500 %")]
        [InlineData(65747.125f, "6,574,712 %")]
        [InlineData(429496.72f, "42,949,672 %")]
        public void TestFormatterSingle_P0(float value, string expectedResult) => TestFormatterSingle_Standard(value, "P0", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.00 %")]
        [InlineData(float.MaxValue, "34,028,234,663,852,885,981,170,418,348,451,692,544,000.00 %")]
        [InlineData(MathF.E, "271.83 %")]
        [InlineData(MathF.PI, "314.16 %")]
        [InlineData(0.0f, "0.00 %")]
        [InlineData(0.0046f, "0.46 %")]
        [InlineData(0.005f, "0.50 %")]
        [InlineData(0.125f, "12.50 %")]
        [InlineData(0.5f, "50.00 %")]
        [InlineData(0.51f, "51.00 %")]
        [InlineData(0.56789f, "56.79 %")]
        [InlineData(0.845512390f, "84.55 %")]
        [InlineData(1.0f, "100.00 %")]
        [InlineData(505.0f, "50,500.00 %")]
        [InlineData(506.0f, "50,600.00 %")]
        [InlineData(545.0f, "54,500.00 %")]
        [InlineData(545.1f, "54,510.00 %")]
        [InlineData(555.0f, "55,500.00 %")]
        [InlineData(65747.125f, "6,574,712.50 %")]
        [InlineData(429496.72f, "42,949,671.88 %")]
        public void TestFormatterSingle_P2(float value, string expectedResult) => TestFormatterSingle_Standard(value, "P2", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.0000 %")]
        [InlineData(float.MaxValue, "34,028,234,663,852,885,981,170,418,348,451,692,544,000.0000 %")]
        [InlineData(MathF.E, "271.8282 %")]
        [InlineData(MathF.PI, "314.1593 %")]
        [InlineData(0.0f, "0.0000 %")]
        [InlineData(0.0046f, "0.4600 %")]
        [InlineData(0.005f, "0.5000 %")]
        [InlineData(0.125f, "12.5000 %")]
        [InlineData(0.5f, "50.0000 %")]
        [InlineData(0.51f, "51.0000 %")]
        [InlineData(0.56789f, "56.7890 %")]
        [InlineData(0.845512390f, "84.5512 %")]
        [InlineData(1.0f, "100.0000 %")]
        [InlineData(505.0f, "50,500.0000 %")]
        [InlineData(506.0f, "50,600.0000 %")]
        [InlineData(545.0f, "54,500.0000 %")]
        [InlineData(545.1f, "54,509.9976 %")]
        [InlineData(555.0f, "55,500.0000 %")]
        [InlineData(65747.125f, "6,574,712.5000 %")]
        [InlineData(429496.72f, "42,949,671.8750 %")]
        public void TestFormatterSingle_P4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "P4", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "0.00000000000000000000 %")]
        [InlineData(float.MaxValue, "34,028,234,663,852,885,981,170,418,348,451,692,544,000.00000000000000000000 %")]
        [InlineData(MathF.E, "271.82817459106445312500 %")]
        [InlineData(MathF.PI, "314.15927410125732421875 %")]
        [InlineData(0.0f, "0.00000000000000000000 %")]
        [InlineData(0.0046f, "0.46000001020729541779 %")]
        [InlineData(0.005f, "0.49999998882412910461 %")]
        [InlineData(0.125f, "12.50000000000000000000 %")]
        [InlineData(0.5f, "50.00000000000000000000 %")]
        [InlineData(0.51f, "50.99999904632568359375 %")]
        [InlineData(0.56789f, "56.78899884223937988281 %")]
        [InlineData(0.845512390f, "84.55123901367187500000 %")]
        [InlineData(1.0f, "100.00000000000000000000 %")]
        [InlineData(505.0f, "50,500.00000000000000000000 %")]
        [InlineData(506.0f, "50,600.00000000000000000000 %")]
        [InlineData(545.0f, "54,500.00000000000000000000 %")]
        [InlineData(545.1f, "54,509.99755859375000000000 %")]
        [InlineData(555.0f, "55,500.00000000000000000000 %")]
        [InlineData(65747.125f, "6,574,712.50000000000000000000 %")]
        [InlineData(429496.72f, "42,949,671.87500000000000000000 %")]
        public void TestFormatterSingle_P20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "P20", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1E-45")]
        [InlineData(float.MaxValue, "3.4028235E+38")]
        [InlineData(MathF.E, "2.7182817")]
        [InlineData(MathF.PI, "3.1415927")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.005")]
        [InlineData(0.125f, "0.125")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.56789")]
        [InlineData(0.845512390f, "0.8455124")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545.1")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65747.125")]
        [InlineData(429496.72f, "429496.72")]
        public void TestFormatterSingle_R(float value, string expectedResult) => TestFormatterSingle_Standard(value, "R", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1E-45")]
        [InlineData(float.MaxValue, "3.4028235E+38")]
        [InlineData(MathF.E, "2.7182817")]
        [InlineData(MathF.PI, "3.1415927")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.005")]
        [InlineData(0.125f, "0.125")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.56789")]
        [InlineData(0.845512390f, "0.8455124")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545.1")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65747.125")]
        [InlineData(429496.72f, "429496.72")]
        public void TestFormatterSingle_R0(float value, string expectedResult) => TestFormatterSingle_Standard(value, "R0", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1E-45")]
        [InlineData(float.MaxValue, "3.4028235E+38")]
        [InlineData(MathF.E, "2.7182817")]
        [InlineData(MathF.PI, "3.1415927")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.005")]
        [InlineData(0.125f, "0.125")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.56789")]
        [InlineData(0.845512390f, "0.8455124")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545.1")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65747.125")]
        [InlineData(429496.72f, "429496.72")]
        public void TestFormatterSingle_R2(float value, string expectedResult) => TestFormatterSingle_Standard(value, "R2", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1E-45")]
        [InlineData(float.MaxValue, "3.4028235E+38")]
        [InlineData(MathF.E, "2.7182817")]
        [InlineData(MathF.PI, "3.1415927")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.005")]
        [InlineData(0.125f, "0.125")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.56789")]
        [InlineData(0.845512390f, "0.8455124")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545.1")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65747.125")]
        [InlineData(429496.72f, "429496.72")]
        public void TestFormatterSingle_R4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "R4", expectedResult);

        [Theory]
        [InlineData(float.Epsilon, "1E-45")]
        [InlineData(float.MaxValue, "3.4028235E+38")]
        [InlineData(MathF.E, "2.7182817")]
        [InlineData(MathF.PI, "3.1415927")]
        [InlineData(0.0f, "0")]
        [InlineData(0.0046f, "0.0046")]
        [InlineData(0.005f, "0.005")]
        [InlineData(0.125f, "0.125")]
        [InlineData(0.5f, "0.5")]
        [InlineData(0.51f, "0.51")]
        [InlineData(0.56789f, "0.56789")]
        [InlineData(0.845512390f, "0.8455124")]
        [InlineData(1.0f, "1")]
        [InlineData(505.0f, "505")]
        [InlineData(506.0f, "506")]
        [InlineData(545.0f, "545")]
        [InlineData(545.1f, "545.1")]
        [InlineData(555.0f, "555")]
        [InlineData(65747.125f, "65747.125")]
        [InlineData(429496.72f, "429496.72")]
        public void TestFormatterSingle_R20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "R20", expectedResult);

        public static IEnumerable<object[]> TestFormatterSingle_InvalidMemberData =>
            from value in new[] { float.Epsilon, float.MaxValue, MathF.E, MathF.PI, 0.0, 0.845512390f, 1.0, 429496.72 }
            from format in new[] { "D", "D4", "D20", "X", "X4", "X20" }
            select new object[] { value, format };

        [Theory]
        [MemberData(nameof(TestFormatterSingle_InvalidMemberData))]
        public void TestFormatterSingle_Invalid(float value, string format) => Assert.Throws<FormatException>(() => InvariantToStringSingle(value, format));

        protected void TestFormatterSingle_Standard(float value, string format, string expectedResult)
        {
            string actualResult = InvariantToStringSingle(value, format);
            Assert.Equal(expectedResult, actualResult);
        }
    }
}
